package com.android.openapp.data;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.io.StreamCorruptedException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;


import android.graphics.Color;
import android.location.Address;
import android.location.Geocoder;
import android.net.Uri;
import android.util.Log;

import com.android.openapp.R;
import com.android.openapp.services.Controller;
import com.socrata.data.View;

import com.socrata.data.View.Row;

/**
 * 
 * @author Allieri Tommaso
 *
 */
public abstract class Place implements Comparable<Place>,Serializable{
	/**
	 * 
	 */
	
	private static final long serialVersionUID = 8301941249560739238L;
	/**
	 * da mettere in un arraylist (xml)
	 * Per inserire un novo dataset basta aggiungere il nome a datasetM[]
	 * listmetadati
	 * [0] musei - iu2c-9p5j
	 * [1] ostelli - 3b7c-6kcq
	 * [2] architetture - kf9b-rj2t
	 */
	public int id;
	public int type;
	private int Bcolor=Color.TRANSPARENT;
	private int photo;
	public int bookmark=0;
	public final static String DENOMINAZIONE="DENOMINAZIONE";
	public final static String TIPOLOGIA="TIPOLOGIA";
	public final static String INDIRIZZO="INDIRIZZO";
	
	public static Geocoder mGeoCoder;
	public static List<View> listmetadati=new ArrayList<View>();
	public static List<View> vuota=new ArrayList<View>();
	public static ArrayList<LinkedHashMap<String, String>> campiHashMap=new ArrayList<LinkedHashMap<String,String>>();
	
	public static String datasetM[];//=new String[] {"iu2c-9p5j","3b7c-6kcq","kf9b-rj2t"};
	public static List<Place> lista=new ArrayList<Place>();//lista principale
	public static List<Place> list_bookmarks=new ArrayList<Place>();
	//public static List<Place> temp=new ArrayList<Place>();
	public Coordinate coord;
	public View metadata;
	public Row row;
	Map<String,Object> data;
	
	public Place() {
		
	}
	
	public void setBookmark(int value){
		this.bookmark=value;
	}
	public static void setGeocoder(Geocoder g){
		Log.i("geocoder","init");
		mGeoCoder = g;
	}
	
	public static void initialize(){
		for(int i=0;i<datasetM.length;i++){
			listmetadati.add(new View());
			
		}
		Log.d("Initialize method","Completed");
		//museo
	}
	
	public void addPlace(Place l){
		lista.add(l);
	}
	
	public static void setPlaces(List<Place> list){
		lista=list;
	}
	
	public Place getPlace(int index){
		return lista.get(index);
	}
	
	
	
	public abstract String getDenominazione();
	public abstract String getTipologia();
	
	//GETTER E SETTER
	
	public int getBcolor(){
		return Bcolor;
	}
	
	public void setBcolor(int color){
		Bcolor=color;
	}
	
	public void setCoord(Double lat,Double lng){
		coord=new Coordinate(lat, lng);
	}
	public void setMetadata(View meta){
		this.metadata=meta;
	}
	public void setRow(Row row){
		this.row=row;
	}
	public void setMapData(Map<String,Object> data){
		this.data=data;
	}
	public void setCoord(String lat,String lng){
		if(lat != null && lng != null)
			coord = new Coordinate(lat, lng);
		else{
			String s = getAddress();
			try {
				Address a = mGeoCoder.getFromLocationName(s, 1).get(0);
				Log.v("place","Geocoding "+s);
				Double latitude = a.getLatitude();
				Double longitude = a.getLongitude();
				coord = new Coordinate(latitude, longitude);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			catch (NullPointerException e){
				coord = new Coordinate();
				Log.w("place", "no coordinates found for "+s);
			}
			catch (IllegalArgumentException e){
				coord = new Coordinate();
				Log.w("place", "no address found");
			}
		}
	}
	
	public Row getRow(){
		return row;
	}
	public View getMetadata(){
		return metadata;
	}
	
	public Double getLatitude(){
		return coord.getLatitudine();
	}
	public Double getLongitude(){
		return coord.getLongitudine();
	}
	public String getStringValue(String campo){
		return (String) data.get(Integer.toString(metadata.getColumnByIdentifier(campo).getId()));
	}
	
	@Override
	public abstract String toString();
	
	public abstract String getAddress();
	
	public abstract String getContactInfo();
	
	public byte[] getBytePlace(){
		
		byte[] data=null;
		ByteArrayOutputStream bos=new ByteArrayOutputStream();
		ObjectOutputStream oos;
		try {
			
			oos = new ObjectOutputStream(bos);
			oos.writeObject(row);
			oos.flush();
			oos.close();
			bos.close();
			
			data=bos.toByteArray();
			
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return data;
		
	}
	public static Row serObject(byte[] Row){
		Row temp=null;
		ByteArrayInputStream bais=new ByteArrayInputStream(Row);
		try {
			ObjectInputStream ins=new ObjectInputStream(bais);
			temp=(Row)ins.readObject();
			
		} catch (StreamCorruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return temp;
	}
	
	public int compareTo(Place another) {
		return (int) (Controller.distanceTo(this) - Controller.distanceTo(another));
//		if(Controller.distanceTo(this)<Controller.distanceTo(another))
//			return -1;
//		if(Controller.distanceTo(this)==Controller.distanceTo(another))
//			return 0;
//		return 1;
	}

	public void setPhotoRes(int resPhoto){
		this.photo=resPhoto;
	}
	public int getPhotoRes() {
		// TODO Auto-generated method stub
		return photo;
	}
	
}
